/* This file will handle the RSA Cryptographic functions. 
 * The method rsaClicked is invoked by clicking on the Cryptografie link on home.jsp*/
function rsaClicked() {
	var width = 900;
	var height = 700;
	var left = (screen.width / 2) - (width / 2);
	var top = (screen.height / 2) - (height / 2);
	popupWindow = window.open('rsa.jsp', 'RSA', 'width=' + width + ',height='
			+ height + ',left=' + left + ',top=' + top);
};

$(document).ready(
		function() {

			/* dummy values */
			var p;
			// 31
			var q;
			// 47
			var n;
			// p*q
			var e;
			// 7
			var d;
			// 1183
			/* dummy values */
					var primes = new Array("17", "19", "23", "29", "31", "37",
							"41", "43", "47", "53", "59", "61", "67", "71",
							"73", "79", "83", "89", "97", "101", "103", "107",
							"109", "113", "127", "131", "137", "139", "149",
							"151", "157", "163", "167", "173", "179", "181",
							"191", "193", "197", "199", "211", "223", "227",
							"229", "233", "239", "241", "251", "257", "263",
							"269", "271", "277", "281", "283", "293", "307",
							"311", "313", "317", "331", "337", "347", "349",
							"353", "359", "367", "373", "379", "383", "389",
							"397", "401", "409", "419", "421", "431", "433",
							"439", "443", "449", "457", "461", "463", "467",
							"479", "487", "491", "499", "503", "509", "521",
							"523", "541", "547", "557", "563", "569", "571",
							"577", "587", "593", "599", "601", "607", "613",
							"617", "619", "631", "641", "643", "647", "653",
							"659", "661", "673", "677", "683", "691", "701",
							"709", "719", "727", "733", "739", "743", "751",
							"757", "761", "769", "773", "787", "797", "809",
							"811", "821", "823", "827", "829", "839", "853",
							"857", "859", "863", "877", "881", "883", "887",
							"907", "911", "919", "929", "937", "941", "947",
							"953", "967", "971", "977", "983", "991", "997");
			var firstKey;
			var secondKey;

			$("#codeCyphertext").click(function() {
				firstKey = $("#rsaKeyOneInput").val();
				secondKey = $("#rsaKeyTwoInput").val();
				if ($.inArray(firstKey, primes) == (-1)) {
					alert("Your first key is not a valid number. It needs to be a prime greater than or equal to 17 and not equal to the other number.");
				} else if ($.inArray(secondKey, primes) == (-1)) {
					alert("Your second key is not a valid number. It needs to be a prime greater than or equal to 17 and not equal to the other number.");
				} else {
					p = firstKey;
					q = secondKey;
					n = p * q;
					var m = (p - 1) * (q - 1);
					e = calculateE(m);
					var textInput = $("#cyphertextInput").val();
					var array = decomposeTextIntoASCIICodes(textInput);
					var encryptedArray = powerMod(array, e, n);
					var encryptedText = createEncryptedString(encryptedArray);
					$("#cyphertextInput").val(encryptedText);
				}
			});

			$("#decodeCyphertext").click(function() {
				firstKey = $("#rsaKeyOneInput").val();
				secondKey = $("#rsaKeyTwoInput").val();
				if ($.inArray(firstKey, primes) == (-1)) {
					alert("Your first key is not a prime number!");
				} else if ($.inArray(secondKey, primes) == (-1)) {
					alert("Your second key is not a prime number!");
				} else {
					p = firstKey;
					q = secondKey;
					n = p * q;
					var m = (p - 1) * (q - 1);
					e = calculateE(m);
					d = inverseModulo(e, m);
					var numberInput = $("#cyphertextInput").val();
					var array = numberInput.split(" ");
					var subCodes = powerMod(array, d, n);
					var clearTextAsArray = formTextFromASCIICodes(subCodes);
					var clearText = createDecryptedString(clearTextAsArray);
					$("#cyphertextInput").val(clearText);
				}
			});

		});

function ggd(a, b) {
	if (b == 0) {
		return a;
	} else {
		return ggd(b, a % b);
	}
}
function inverseModulo(a, modb) {
	return berekenInverse(a, 2, modb)
}

function berekenInverse(a, i, modb) {
	if ((a * i) % modb == 1) {
		return i;
	} else {
		return (berekenInverse(a, i + 1, modb));
	}
}

function modulo(input, modulo) {
	var output = input;
	if (output < modulo) {
	} else {
		while (output >= modulo) {
			output = output - modulo;
		}
		;
	}
	;
	return output;
}

function powerMod(inputArray, exponent, n) {
	var resultArray = new Array();
	var j = 0;
	while (j < inputArray.length) {
		var i = exponent - 1;
		var encryptedText = modulo(inputArray[j], n);
		var resultText = encryptedText;
		while (i != 0) {
			resultText = (resultText * encryptedText)%n;
			i--;
		}
		;
		resultArray[j] = resultText;
		j++;
	}
	;
	return resultArray;
}

/*
 * ENCRYPTION
 */
function calculateE(n) {
	var e = 3;
	var temp = ggd(e, n);
	while (temp != 1) {
		e = e + 1;
		temp = ggd(e, n);
	}
	return e;
}
function decomposeTextIntoASCIICodes(textInput) {
	var array = new Array();
	var length = textInput.length;
	var i = 0;
	while (i < length) {
		var char = textInput.charAt(i);
		var code = textInput.charCodeAt(i);
		array[i] = code;
		i++;
	}
	;
	return array;
}

function createEncryptedString(inputArray) {
	var l = inputArray.length;
	var i = 0;
	var result = "";
	while (i < l) {
		if (i == 0) {
			result = result + inputArray[i];
		} else {
			result = result + " " + inputArray[i];
		}
		i++;
	}
	return result;
}

// function composeTextFromArray(codesArray){
// var j = 0;
// var text = "";
// while(j<codesArray.length){
// text = text+codesArray[j];
// j++;
// };
// return number;
// }

/*
 * DECRYPTION
 */

function formTextFromASCIICodes(inputArray) {
	var array = new Array();
	var length = inputArray.length;
	var i = 0;
	while (i < length) {
		array[i] = String.fromCharCode(inputArray[i]);
		i++;
	}
	;
	return array;
}

function createDecryptedString(inputArray) {
	var l = inputArray.length;
	var i = 0;
	var result = "";
	while (i < l) {
		result = result + inputArray[i];
		i++;
	}
	return result;
}